#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <fcntl.h>

#define LEN_ENV 20
#define LEN_RFID 4 
#define DEV_ZIGBEE "/dev/ttyUSB0"

#define err_log(log)\
do{\
	perror(log);\
	exit(1);\
}while(0)  //出错处理的宏函数

int dev_uart_fd;

typedef struct sockaddr SA;

typedef struct msg_pack
{
	char msg_type;
	char text[27];
}link_datatype;

struct getEnvMsg
{
	unsigned char sto_no;
	unsigned char tem[2];
	unsigned char hum[2];
	unsigned char x;
	unsigned char y;
	unsigned char z;
	unsigned int ill;
	unsigned int battery;
	unsigned int adc;
};

struct sendEnv
{
	uint8_t head[3];	 //标识位st:
	uint8_t type;		 //数据类型
	uint8_t snum;		 //仓库编号
	uint8_t temp[2];	 //温度	
	uint8_t hum[2];		 //湿度
	uint8_t x;			 //三轴信息
	uint8_t y;			
	uint8_t z;			
	uint32_t ill;		 //光照
	uint32_t bet;		 //电池电量
	uint32_t adc; 		 //电位器信息
};

float dota_adc (unsigned int ratio)
{
	return ((ratio * 3.3) / 1024);
}

float dota_atof (char unitl)
{
	if (unitl > 100)
	{
		return unitl / 1000.0;
	}
	else if (unitl > 10)
	{
		return unitl / 100.0;
	}
	else
	{
		return unitl / 10.0;
	}
}

void serial_init(int fd)
{
	struct termios options;
	tcgetattr(fd, &options);
	options.c_cflag |= ( CLOCAL | CREAD );
	options.c_cflag &= ~CSIZE;
	options.c_cflag &= ~CRTSCTS;
	options.c_cflag |= CS8;
	options.c_cflag &= ~CSTOPB; 
	options.c_iflag |= IGNPAR;
	options.c_iflag &= ~(ICRNL | IXON);
	options.c_oflag = 0;
	options.c_lflag = 0;

	cfsetispeed(&options, B115200);
	cfsetospeed(&options, B115200);
	tcsetattr(fd,TCSANOW,&options);
}

int main(int argc,const char *argv[])
{
	int sockfd;
	char sockbuf[32]={0};
	struct sockaddr_in serveraddr;
	struct sendEnv myData;
	socklen_t socklen=sizeof(serveraddr);
	bzero(&serveraddr,socklen);

	int i = 0, len;
	char flag = 0, check;
	link_datatype buf;

	if(argc<3)
	{
		fprintf(stderr,"USER:%s IP PORT",argv[0]);
		return -1;
	}

	if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)//创建流式套接字
	{
		err_log("fail to socket:");
	}

	//填充服务器的网络信息
	serveraddr.sin_family=AF_INET;
	serveraddr.sin_port=htons(atoi(argv[2]));
	serveraddr.sin_addr.s_addr=inet_addr(argv[1]);

	if(connect(sockfd,(SA*)&serveraddr,socklen)<0)//请求链接服务器
	{
		err_log("fail to connect:");
	}


	
	if ((dev_uart_fd = open (DEV_ZIGBEE, O_RDWR)) < 0)
	{
		perror ("open DEV_ZIGBEE");
		return -1;
	}

	serial_init (dev_uart_fd);

	printf ("pthread_transfer is ok\n");

	while (1)
	{
		memset (&buf, 0, sizeof (link_datatype));
		read (dev_uart_fd, &check, 1);
		if (check == 's')
		{
			check = 0;
			read (dev_uart_fd, &check, 1);
			if (check == 't')
			{
				check = 0;
				read (dev_uart_fd, &check, 1);
				if (check == ':')
				{
					check = 0;
					read (dev_uart_fd, &check, 1);
					if (check == 'e')
					{
						buf.msg_type = 'e';
						usleep(1);
						if ((len = read (dev_uart_fd, buf.text, LEN_ENV)) != LEN_ENV)
						{
							for (i = len; i < LEN_ENV; i++)
							{
								read (dev_uart_fd, buf.text+i, 1);
							}
						}
						flag = 1;
					}
				}
			}
		}
		
		if (1 == flag)
		{
			struct getEnvMsg pack;
			memcpy (&pack, buf.text, 20);
			int sto_no = pack.sto_no;
			printf ("no = %d tem = %0.2f hum = %0.2f ill = %0.2f battery = %0.2f adc = %0.2f x = %d y = %d z = %d\n", sto_no,
			(double)(pack.tem[0] + dota_atof (pack.tem[1])), (double)(pack.hum[0] + dota_atof (pack.hum[1])), (double)(pack.ill), (double)(dota_adc(pack.battery)), (double)(dota_adc(pack.adc)), pack.x, pack.y, pack.z);

			myData.temp[0] = pack.tem[0];
			myData.temp[1] = pack.tem[1];
			myData.hum[0] = pack.hum[0];
			myData.hum[1] = pack.hum[1];
			myData.ill = pack.ill;
			myData.bet = pack.battery;
			myData.adc = pack.adc;
			myData.x = pack.x;
			myData.y = pack.y;
			myData.z = pack.z;

			send(sockfd,&myData,sizeof(myData),0);
		}
		
	}

}
